package com.yuliang.ai.sync;

import com.alibaba.fastjson.JSONObject;
import com.yuliang.ai.domain.Dto.*;
import com.yuliang.ai.domain.Vo.ChatDoubaoVo;
import com.yuliang.ai.domain.Vo.HotelVo;
import com.yuliang.ai.domain.Vo.ScenicWithFilterVo;
import com.yuliang.ai.domain.Vo.TripRouteVo;
import com.yuliang.ai.service.HotelService;
import com.yuliang.ai.service.ScenicService;
import com.yuliang.ai.service.TripRouteService;
import com.yuliang.ai.websocket.WebSocketServer;
import com.yuliang.utils.util.RedisUtils;
import com.yuliang.utils.util.StringUtils;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import sun.security.pkcs11.wrapper.Constants;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author Huangkai
 */
@Slf4j
@Component
public class ThreadAsync {

    @Autowired
    HotelService hotelService;

    @Autowired
    WebSocketServer messagePushWebSocket;

    @Autowired
    ScenicService scenicService;

    @Autowired
    TripRouteService tripRouteService;


    /**
     * 异步返回给客户端websocket
     * @param chatDoubaoVo
     * @param allContent
     * @param resultJSON
     */
    @SneakyThrows
    @Async("asyncThreadConfig")
    public void asyncWebsocket(JSONObject resultJSON, ChatDoubaoVo chatDoubaoVo, String allContent, String chatKeyLock) {
        log.info("进入到异步通信发送数据。。。");
        //历史上下文
        String historyContextKey = chatDoubaoVo.getUserId() + chatDoubaoVo.getHumanIdentifyId() + chatDoubaoVo.getDeviceId();
        //历史记录
        StringBuffer historyResultContent = new StringBuffer();
        String connectionKey = chatDoubaoVo.getDeviceId() + chatDoubaoVo.getUserId() + chatDoubaoVo.getHumanIdentifyId();
        String aiJsonDtoStr = null;
        String content = "";
        if(allContent.indexOf("{") >=0 && allContent.indexOf("}") >=0){
            String jsonStr = allContent.substring(allContent.indexOf("{"), allContent.indexOf("}") + 1);
            if(StringUtils.isNotEmpty(jsonStr)){
                aiJsonDtoStr = jsonStr;
            }
            content = allContent.substring(allContent.indexOf("}") + 1);
        }else{
            content = allContent;
        }
        log.info("传的给客户端的数据{}", content);
        List<String> splitContentList = new ArrayList<>();
        historyResultContent.append(content);
        int t = (content.length() / 20);
        if(t == 0){
            splitContentList.add(content);
        }else{
            for(int i = 0 ;i<= (t-1); i++){
                splitContentList.add(content.substring(i*20, (i+1) * 20));
            }
            int k = (content.length() % 20);
            //不能整除
            if(k != 0){
                splitContentList.add(content.substring(t*20));
            }
        }
        for(int i = 0; i < splitContentList.size(); i++){
            String returnContent = splitContentList.get(i);
            if(i == (splitContentList.size() - 1)){
                resultJSON.put("content", returnContent);
                resultJSON.put("isEnd", 0);
                if(StringUtils.isNotEmpty(aiJsonDtoStr)){
                    resultJSON.put("isEnd", 1);
                }
            }else{
                resultJSON.put("content", returnContent);
                resultJSON.put("isEnd", 0);
            }
            Thread.sleep(500);
            if(RedisUtils.hasKey(connectionKey)){
                String requestId = RedisUtils.get(connectionKey);
                if(requestId.equals(chatDoubaoVo.getRequestId())){
                    RedisUtils.delete(connectionKey);
                    return;
                }
            }
            log.info("打印判断大模型是否当前会话的返回结果-----");
            //查询锁是否存在
            if(RedisUtils.hasKey(chatKeyLock)){
                String currentChatInfo = chatDoubaoVo.getChatId()+ chatDoubaoVo.getChatAnsId() + "";
                String value = RedisUtils.get(chatKeyLock);
                if(!currentChatInfo.equals(value)){
                    return;
                }
                messagePushWebSocket.sendOneMessage(chatDoubaoVo.getDeviceId(), resultJSON);
            }
        }
        log.info("传给一键游的json{}", aiJsonDtoStr);
        if(StringUtils.isNotEmpty(aiJsonDtoStr)){
            JSONObject jsonObject = JSONObject.parseObject(aiJsonDtoStr);
            if(jsonObject.getString("type").equals("1")){
                AiJsonHotelDto aiJsonHotelDto = jsonObject.toJavaObject(AiJsonHotelDto.class);
                requestHotel(chatDoubaoVo, aiJsonHotelDto);
            }else if(jsonObject.getString("type").equals("2")){
                AiJsonScenicDto aiJsonScenicDto = jsonObject.toJavaObject(AiJsonScenicDto.class);
                requestScenic(chatDoubaoVo, aiJsonScenicDto);
            }else{
                AiJsonRouteDto aiJsonRouteDto = jsonObject.toJavaObject(AiJsonRouteDto.class);
                requestRoute(chatDoubaoVo, aiJsonRouteDto);
            }
        }
        //历史识别记录
        if(historyResultContent.length() > 0){
            //设置过期时间为5分钟
            RedisUtils.hPut(historyContextKey, chatDoubaoVo.getTitle(), historyResultContent.toString());
            //设置过期时间
            RedisUtils.expire(historyContextKey, 5, TimeUnit.MINUTES);
        }
        RedisUtils.delete(connectionKey);
    }
    /***
     * 请求酒店
     */
    public void requestHotel(ChatDoubaoVo chatDoubaoVo, AiJsonHotelDto aiJsonHotelDto) {
        JSONObject hotelObject = new JSONObject();
        HotelVo hotelVo = new HotelVo();
        hotelVo.setCity(aiJsonHotelDto.getCity());
        hotelVo.setKeyWord(aiJsonHotelDto.getKeyWord());
        hotelVo.setMeals(aiJsonHotelDto.getBrand());
        hotelVo.setTheme(aiJsonHotelDto.getTheme());
        hotelVo.setBrand(aiJsonHotelDto.getBrand());

        if(StringUtils.isNotEmpty(aiJsonHotelDto.getMaxPrice()) && !aiJsonHotelDto.getMaxPrice().equals("")){
            hotelVo.setMaxPrice(Float.parseFloat(aiJsonHotelDto.getMaxPrice()));
        }
        if(StringUtils.isNotEmpty(aiJsonHotelDto.getMinPrice()) && !aiJsonHotelDto.getMinPrice().equals("")){
            hotelVo.setMaxPrice(Float.parseFloat(aiJsonHotelDto.getMinPrice()));
        }
        //查询酒店信息
        TourCommonDto hotelListDto = hotelService.selectHotelInfo(hotelVo);
        hotelObject.put("hotelInfo", hotelListDto);
        setReturnData(hotelObject, chatDoubaoVo, Integer.parseInt(aiJsonHotelDto.getType()));
    }
    /***
     * 景点
     */
    public void requestScenic(ChatDoubaoVo chatDoubaoVo, AiJsonScenicDto aiJsonScenicDto){
        ScenicWithFilterVo scenicWithFilterVo = new ScenicWithFilterVo();
        scenicWithFilterVo.setCity(aiJsonScenicDto.getCity());
        scenicWithFilterVo.setKeyWord(aiJsonScenicDto.getKeyWord());
        scenicWithFilterVo.setLevel(aiJsonScenicDto.getLevel());
        scenicWithFilterVo.setResCategory(aiJsonScenicDto.getResCategory());

        JSONObject hotelObject = new JSONObject();
        TourCommonDto tourCommonDto = scenicService.selectScenicWithFilter(scenicWithFilterVo);
        if(tourCommonDto != null){
            hotelObject.put("hotelInfo", tourCommonDto);
            setReturnData(hotelObject, chatDoubaoVo, Integer.parseInt(aiJsonScenicDto.getType()));
        }
    }
    public void requestRoute(ChatDoubaoVo chatDoubaoVo, AiJsonRouteDto aiJsonRouteDto) {
        TripRouteVo tripRouteVo = new TripRouteVo();
        tripRouteVo.setKeyWord(aiJsonRouteDto.getKeyword());
        tripRouteVo.setFromCityCode(aiJsonRouteDto.getFromCityCode());
        tripRouteVo.setToCityCode(aiJsonRouteDto.getToCityCode());
        if(StringUtils.isNotEmpty(aiJsonRouteDto.getMaxPrice()) && !aiJsonRouteDto.getMaxPrice().equals("")){
            tripRouteVo.setMaxPrice(Float.parseFloat(aiJsonRouteDto.getMaxPrice()));
        }
        if(StringUtils.isNotEmpty(aiJsonRouteDto.getMinPrice()) && !aiJsonRouteDto.getMinPrice().equals("")){
            tripRouteVo.setMaxPrice(Float.parseFloat(aiJsonRouteDto.getMinPrice()));
        }
        JSONObject hotelObject = new JSONObject();
        TourCommonDto tourCommonDto = tripRouteService.getTripRouteInfosByFilter(tripRouteVo);
        if(tourCommonDto != null){
            hotelObject.put("hotelInfo", tourCommonDto);
            setReturnData(hotelObject, chatDoubaoVo, Integer.parseInt(aiJsonRouteDto.getType()));
        }
    }

    public void setReturnData(JSONObject hotelObject, ChatDoubaoVo chatDoubaoVo, Integer type){
        hotelObject.put("chatId", chatDoubaoVo.getChatId());
        hotelObject.put("chatAnsId", chatDoubaoVo.getChatAnsId());
        hotelObject.put("type", type);
        hotelObject.put("isEnd", 1);
        hotelObject.put("content", "");
        hotelObject.put("videoPathList", new ArrayList<>());
        hotelObject.put("imgList", new ArrayList<>());
        messagePushWebSocket.sendOneMessage(chatDoubaoVo.getDeviceId(), hotelObject);
    }
}
